package cn.chiship.sdk.third.baidu;

import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.exception.ExceptionUtil;
import cn.chiship.sdk.core.exception.custom.BusinessException;
import cn.chiship.sdk.core.properties.CommonConfigProperties;
import cn.chiship.sdk.core.util.RedisUtil;
import cn.chiship.sdk.core.util.StringUtil;
import cn.chiship.sdk.core.util.http.HttpUtils;
import cn.chiship.sdk.third.core.common.ThirdConstants;
import cn.chiship.sdk.third.core.model.baidu.BaiDuOcrConfigModel;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * 百度OCR
 *
 * @author lijian
 * <p>
 * BaiDuOcrUtils baiDuOcrUtils = BaiDuOcrUtils.getInstance() .config() .token();
 */
public class BaiDuOcrUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(BaiDuOcrUtils.class);

    CommonConfigProperties commonConfigProperties = CommonConfigProperties.getInstance();

    public static final String IMAGE_JPEG_BASE64 = "data:image/jpeg;base64,";

    public static final String IMAGE_PNG_BASE64 = "data:image/png;base64,";

    public static final String STRING_URL = "url";

    public static final String STRING_IMAGE = "image";

    private static final String ACCESS_TOKEN = "access_token";

    private BaiDuOcrConfigModel baiDuOcrConfigModel;

    private static BaiDuOcrUtils instance;

    private String accessToken = null;

    private BaiDuOcrUtils() {
    }

    public static synchronized BaiDuOcrUtils getInstance() {
        if (instance == null) {
            instance = new BaiDuOcrUtils();
        }
        return instance;
    }

    public BaiDuOcrUtils config() {
        this.baiDuOcrConfigModel = new BaiDuOcrConfigModel(commonConfigProperties.getValue("third.ai.baidu.apiKey"),
                commonConfigProperties.getValue("third.ai.baidu.secretKey"),
                commonConfigProperties.getValue("third.ai.baidu.appId")

        );
        return this;
    }

    public BaiDuOcrUtils config(BaiDuOcrConfigModel baiDuOcrConfigModel) {
        this.baiDuOcrConfigModel = baiDuOcrConfigModel;
        return this;
    }

    public BaiDuOcrUtils token() {
        BaseResult baseResult = getToken();
        if (!baseResult.isSuccess()) {
            throw new BusinessException(JSON.toJSONString(baseResult.getData()));
        }
        this.accessToken = baseResult.getData().toString();
        return this;
    }

    /**
     * 获得accessToken
     *
     * @return 结果 返回token
     */
    public BaseResult getToken() {
        String key = ThirdConstants.REDIS_BAI_DU_AIP_ACCESS_TOKEN + ":" + this.baiDuOcrConfigModel.getAppKey();
        String token = RedisUtil.get(key);
        if (!StringUtil.isNullOrEmpty(token)) {
            return BaseResult.ok(token);
        }
        Map<String, String> query = new HashMap<>(7);
        query.put("grant_type", "client_credentials");
        query.put("client_id", this.baiDuOcrConfigModel.getAppKey());
        query.put("client_secret", this.baiDuOcrConfigModel.getAppSecret());
        try {
            BaseResult baseResult = HttpUtils.doPost(BaiDuAiConstant.AIP_SERVER_HOST, BaiDuAiConstant.GET_TOKEN,
                    BaiDuAiConstant.commonHeaders(), query, new HashMap<>(2));
            baseResult = BaiDuAiConstant.analysisAipHttpResponse(baseResult);
            if (!baseResult.isSuccess()) {
                return baseResult;
            }
            com.alibaba.fastjson.JSONObject dataJson = (com.alibaba.fastjson.JSONObject) baseResult.getData();
            String accessToken = dataJson.getString(ACCESS_TOKEN);
            int expiresIn = dataJson.getInteger("expires_in");
            baseResult.setData(accessToken);
            RedisUtil.set(key, accessToken, expiresIn);
            return baseResult;
        } catch (Exception e) {
            LOGGER.error("发生异常", e);
            return ExceptionUtil.formatException(e);
        }
    }

    /**
     * 身份证识别
     *
     * @param image   图片路径 base64图片或网络图片
     * @param isFront 身份证类型,true:正面,false:反面
     * @return 结果
     */
    public BaseResult idCardOcr(String image, Boolean isFront, Boolean isNetwork) {
        String idCardSide;
        if (Boolean.TRUE.equals(isFront)) {
            idCardSide = "front";
        } else {
            idCardSide = "back";
        }

        HashMap<String, String> query = new HashMap<>(2);
        query.put(ACCESS_TOKEN, getAccessToken());
        HashMap<String, String> body = new HashMap<>(2);
        if (Boolean.TRUE.equals(isNetwork)) {
            body.put(STRING_URL, image);
        } else {
            body.put(STRING_IMAGE, replaceImage(image));
        }
        body.put("id_card_side", idCardSide);
        body.put("detect_direction", "true");
        body.put("detect_risk", "false");
        BaseResult baseResult = HttpUtils.doPost(BaiDuAiConstant.AIP_SERVER_HOST, BaiDuAiConstant.ID_CARD,
                BaiDuAiConstant.commonHeaders(), query, body);
        baseResult = BaiDuAiConstant.analysisAipHttpResponse(baseResult);
        return BaiDuAiResultAnalyze.analyzeIdCard(baseResult);
    }

    /**
     * 银行卡识别
     *
     * @param image     图片路径 base64图片或网络图片
     * @param isNetwork 是否网络图片
     * @return 结果
     */
    public BaseResult bankCard(String image, Boolean isNetwork) {

        HashMap<String, String> query = new HashMap<>(2);
        query.put(ACCESS_TOKEN, getAccessToken());
        HashMap<String, String> body = new HashMap<>(2);
        if (Boolean.TRUE.equals(isNetwork)) {
            body.put(STRING_URL, image);
        } else {
            body.put(STRING_IMAGE, replaceImage(image));
        }
        BaseResult baseResult = HttpUtils.doPost(BaiDuAiConstant.AIP_SERVER_HOST, BaiDuAiConstant.BANK_CARD,
                BaiDuAiConstant.commonHeaders(), query, body);
        baseResult = BaiDuAiConstant.analysisAipHttpResponse(baseResult);
        return BaiDuAiResultAnalyze.analyzeBankCard(baseResult);

    }

    /**
     * 营业执照
     *
     * @param image     图片路径 base64图片或网络图片
     * @param isNetwork 是否网络图片
     * @return 结果
     */
    public BaseResult businessLicense(String image, Boolean isNetwork) {
        HashMap<String, String> query = new HashMap<>(2);
        query.put(ACCESS_TOKEN, getAccessToken());
        HashMap<String, String> body = new HashMap<>(2);
        if (Boolean.TRUE.equals(isNetwork)) {
            body.put(STRING_URL, image);
        } else {
            body.put(STRING_IMAGE, replaceImage(image));
        }
        BaseResult baseResult = HttpUtils.doPost(BaiDuAiConstant.AIP_SERVER_HOST, BaiDuAiConstant.BUSINESS_LICENSE,
                BaiDuAiConstant.commonHeaders(), query, body);
        baseResult = BaiDuAiConstant.analysisAipHttpResponse(baseResult);
        return BaiDuAiResultAnalyze.analyzeBusinessLicense(baseResult);

    }

    /**
     * 护照
     *
     * @param image     图片路径 base64图片或网络图片
     * @param isNetwork 是否网络图片
     * @return 结果
     */
    public BaseResult passport(String image, Boolean isNetwork) {
        HashMap<String, String> query = new HashMap<>(2);
        query.put(ACCESS_TOKEN, getAccessToken());
        HashMap<String, String> body = new HashMap<>(2);
        if (Boolean.TRUE.equals(isNetwork)) {
            body.put(STRING_URL, image);
        } else {
            body.put(STRING_IMAGE, replaceImage(image));
        }
        BaseResult baseResult = HttpUtils.doPost(BaiDuAiConstant.AIP_SERVER_HOST, BaiDuAiConstant.PASS_PORT,
                BaiDuAiConstant.commonHeaders(), query, body);
        baseResult = BaiDuAiConstant.analysisAipHttpResponse(baseResult);
        return BaiDuAiResultAnalyze.analyzePassport(baseResult);

    }

    /**
     * 社保卡
     *
     * @param image     图片路径 base64图片或网络图片
     * @param isNetwork 是否网络图片
     * @return 结果
     */
    public BaseResult socialSecurityCard(String image, Boolean isNetwork) {
        HashMap<String, String> query = new HashMap<>(2);
        query.put(ACCESS_TOKEN, getAccessToken());
        HashMap<String, String> body = new HashMap<>(2);
        if (Boolean.TRUE.equals(isNetwork)) {
            body.put(STRING_URL, image);
        } else {
            body.put(STRING_IMAGE, replaceImage(image));
        }
        BaseResult baseResult = HttpUtils.doPost(BaiDuAiConstant.AIP_SERVER_HOST, BaiDuAiConstant.SOCIAL_SECURITY_CARD,
                BaiDuAiConstant.commonHeaders(), query, body);
        baseResult = BaiDuAiConstant.analysisAipHttpResponse(baseResult);
        return BaiDuAiResultAnalyze.analyzeSocialSecurityCard((baseResult));

    }

    /**
     * 车牌识别
     *
     * @param image     图片路径 base64图片或网络图片
     * @param isNetwork 是否网络图片
     * @return 结果
     */
    public BaseResult licensePlate(String image, Boolean isNetwork) {
        HashMap<String, String> query = new HashMap<>(2);
        query.put(ACCESS_TOKEN, getAccessToken());
        HashMap<String, String> body = new HashMap<>(2);
        if (Boolean.TRUE.equals(isNetwork)) {
            body.put(STRING_URL, image);
        } else {
            body.put(STRING_IMAGE, replaceImage(image));
        }
        BaseResult baseResult = HttpUtils.doPost(BaiDuAiConstant.AIP_SERVER_HOST, BaiDuAiConstant.LICENSE_PLATE,
                BaiDuAiConstant.commonHeaders(), query, body);
        baseResult = BaiDuAiConstant.analysisAipHttpResponse(baseResult);
        return BaiDuAiResultAnalyze.analyzeLicensePlate((baseResult));

    }

    private String replaceImage(String image) {
        return image.replace(IMAGE_PNG_BASE64, "").replace(IMAGE_JPEG_BASE64, "");
    }

    public String getAccessToken() {
        if (StringUtil.isNullOrEmpty(accessToken)) {
            throw new BusinessException(
                    "token为空！请链式调用如下方法：DingTalkServicesUtils.getInstance().config().token()获得Token");
        }
        return accessToken;
    }

}
